/*
 *@description: mixin参照类, 修复多选的初始化、添加BUG, 在代码中进行如下修改：
 *              表格的selection中添加:reserve-selection="true"属性；
 *              表格的操作列中，将fieldDefaultKey改为fieldKeyComputed；
 *              后台配置qry_keys查询条件，传入值与externalSelectedRowKeys相等。
 *        可选：选择全部，绑定doSelectedAll事件，用于清除全部的选择数据。
 *@author: liuchenguang
 *@date: 2022-02-18
 *@version: V1.0.0
 */
/** mixin_base */
import { mixin_base } from '@tapui/mixins/mixin_base'
/** 工具类 */
import { filterObjectNull, rmbFormat } from '@tapui/utils/util'
import { validateNull } from '@tapui/utils/validate'
import { formatDate } from '@tapui/utils/date'
import { getAction } from '@tapui/utils/http'
/** 常量 */
import topscommConst from '@tapui/const/tapConst'
/** 组件定义 */
export const mixin_ref_list = {
  mixins: [mixin_base],
  /** 组件数据 */
  data() {
    return {
      // 参照是否显示
      visible: false,
      // 查询操作遮幕
      loading: false,
      // 选中的数据
      selectedRows: [],
      selectedRowKeys: [],
      // 默认Key字段名
      fieldDefaultKey: 'id',
      // 默认显示字段名
      fieldDefaultValue: 'name',
      // URL参数
      url: {},
      // 是否搜索界面
      isSearchDisplay: true,
      // 查询参数
      queryParam: {},
      // 筛选参数
      filtersInfo: {},
      // 列表数据
      datas: [],
      // 默认表格高度
      tableHeight: '480px',
      // 分页参数
      pageInfo: {
        currentPage: 1,
        pageSize: 10,
        pageSizes: ['10', '50', '100'],
        totalCount: 0
      },
      // 排序参数
      sortInfo: {
        sidx: 'sortcode',
        sord: 'asc'
      },
      // 当前单击行
      clickRowkey: '',
      // 外部选中数据列表
      externalSelectedRowKeyList: []
    }
  },
  /** 组件传递参数 */
  props: {
    // 是否单选
    isSingleSelect: {
      default: true,
      type: Boolean
    },
    // 是否可用（只读）
    disabled: {
      default: false,
      type: Boolean
    },
    // key字段名称
    fieldKey: {
      default: '',
      type: String
    },
    // value字段名称
    fieldValue: {
      default: '',
      type: String
    },
    // 参照界面标题
    title: {
      default: '参照选择',
      type: String
    },
    // 参照已选中数据（外部）
    externalSelectedRowKeys: {
      default: '',
      type: String
    },
    // 传入查询参数（外部）
    externalQueryParam: {
      default: () => ({}),
      type: Object
    }
  },
  /** 计算属性 */
  computed: {
    fieldKeyComputed() {
      if (validateNull(this.fieldKey)) {
        return this.fieldDefaultKey
      } else {
        return this.fieldKey
      }
    },
    fieldValueComputed() {
      if (validateNull(this.fieldValue)) {
        return this.fieldDefaultValue
      } else {
        return this.fieldValue
      }
    }
  },
  methods: {
    /** 打开对话框 */
    open() {
      this.initRef()
    },
    /** 初始化参照 */
    initRef() {
      this.datas = []
      this.$nextTick(() => {
        this.doClearSelected()
        this.resetQueryParam()
        if (!validateNull(this.externalSelectedRowKeys)) {
          this.externalSelectedRowKeyList = this.externalSelectedRowKeys.split(',')
        }
        this.doQuery()
      })
    },
    /** 重置查询参数 */
    resetQueryParam() {
      let exclude = ['qry_includeSub']
      for (let key of Object.keys(this.queryParam)) {
        if (!exclude.includes(key)) {
          this.queryParam[key] = ''
        }
      }
      this.pageInfo.currentPage = 1
      this.pageInfo.totalCount = 0
    },
    /** 执行查询 */
    doQuery() {
      this.loadData({ currentPage: 1 })
    },
    /** 查询数据 */
    loadData(paramMap) {
      if (!this.url.list) {
        this.$tap.alert('请设置查询数据地址!')
        return
      }
      // 加载数据 若传入参数1则加载第一页的内容
      if (validateNull(paramMap) === false && Object.keys(paramMap).indexOf('currentPage') > -1) {
        this.pageInfo.currentPage = paramMap['currentPage']
      }
      // 查询条件
      let params = this.getQueryParams()
      this.loading = true
      getAction(this.url.list, params)
        .then((res) => {
          if (res.success) {
            this.datas = res.result.dataList
            this.pageInfo.totalCount = res.result.totalCount
            this.initExternalData()
          } else {
            this.$tap.alert(res.message)
          }
          this.loading = false
        })
        .catch((err) => {
          console.error(err)
        })
        .finally(() => {
          this.loading = false
        })
    },
    /** 对外部传来的数据进行初始化操作 */
    initExternalData() {
      if (this.isSingleSelect || validateNull(this.externalSelectedRowKeyList)) {
        return
      }
      this.$nextTick(() => {
        this.datas.forEach((item) => {
          // 判断当前数据是否为外部已选中数据
          const externalSelectedRowKeyIndex = this.externalSelectedRowKeyList.findIndex((v) => v.toString() === item[this.fieldKeyComputed].toString())
          if (externalSelectedRowKeyIndex > -1) {
            this.$refs.mainTable.toggleRowSelection(item)
            // 从待初始化的数据列表中移除
            this.externalSelectedRowKeyList.splice(externalSelectedRowKeyIndex, 1)
          }
        })
      })
    },
    /** 获取查询参数 */
    getQueryParams() {
      let param = {}
      Object.assign(param, this.queryParam, this.externalQueryParam, this.filtersInfo, this.sorterInfo)
      param.currentPage = this.pageInfo.currentPage
      param.pageSize = this.pageInfo.pageSize
      return filterObjectNull(param)
    },
    // 格式化日期 yyyy-MM-dd
    dateFormat(row, column, cellValue, index) {
      let dateValue = row[column.property]
      if (dateValue && dateValue.length > 0) {
        return formatDate(new Date(dateValue.replace(new RegExp(/-/gm), '/')), 'yyyy-MM-dd')
      } else {
        return ''
      }
    },
    /** 格式化日期 yyyy-MM-dd HH:mm:ss */
    dateTimeFormat(row, column, cellValue, index) {
      let dateValue = row[column.property]
      if (dateValue && dateValue.length > 0) {
        return formatDate(new Date(dateValue.replace(new RegExp(/-/gm), '/')), 'yyyy-MM-dd HH:mm:ss')
      } else {
        return ''
      }
    },
    /** 格式化金额 ￥223,322.20 */
    moneyFormat(row, column, cellValue, index) {
      let moneyValue = row[column.property]
      if (typeof moneyValue === 'undefined' || moneyValue === null || moneyValue === '') {
        return '￥0.00'
      }
      return rmbFormat(moneyValue)
    },
    /** 表格双击事件 */
    doRowDbClick(row, column, event) {
      this.doSelectData(row[this.fieldKeyComputed])
    },
    /** 单选数据 */
    doSelectData(paramKey) {
      this.selectedRows = []
      this.selectedRowKeys = []
      let tempData = this.datas.find((item) => {
        return item[this.fieldKeyComputed] === paramKey
      })
      if (validateNull(tempData)) {
        this.$tap.alert('请选择数据!')
        return
      }
      // 填充数据
      this.selectedRows.push(tempData)
      this.selectedRowKeys.push(tempData[this.fieldKeyComputed])
      // 参照为单选时关闭窗口
      if (this.isSingleSelect) {
        let selectedValue = tempData[this.fieldValueComputed]
        this.$emit('confirm', this.selectedRows[0], this.selectedRowKeys[0], selectedValue)
        this.visible = false
      }
    },
    /** 多选数据 */
    async doConfirm() {
      let selectedValues = ''
      let selectedKeys = ''
      let externalSelectData = []
      if (!validateNull(this.externalSelectedRowKeyList)) {
        externalSelectData = await this.getExternalSelectedRow().catch((err) => {
          console.error(err)
        })
        // 查找未进行初始化的外部数据，重新添加
        externalSelectData.forEach((item) => {
          selectedValues += item[this.fieldValueComputed] + ','
          selectedKeys += item[this.fieldKeyComputed] + ','
        })
        this.externalSelectedRowKeyList = []
      }
      this.selectedRows.forEach((item) => {
        selectedValues += item[this.fieldValueComputed] + ','
      })
      this.selectedRows.forEach((item) => {
        selectedKeys += item[this.fieldKeyComputed] + ','
      })
      if (selectedValues.length > 0) {
        selectedValues = selectedValues.substring(0, selectedValues.length - 1)
      }
      if (selectedKeys.length > 0) {
        selectedKeys = selectedKeys.substring(0, selectedKeys.length - 1)
      }
      this.$emit('confirm', [...externalSelectData, ...this.selectedRows], selectedKeys, selectedValues)
      this.visible = false
    },
    /** 获取未初始化的外部数据 */
    getExternalSelectedRow() {
      return new Promise((resolve, reject) => {
        const param = {
          qry_fieldkey: this.fieldKeyComputed,
          qry_keys: this.externalSelectedRowKeyList.join(',')
        }
        getAction(this.url.list, param)
          .then((res) => {
            if (!res.success) {
              this.$tap.alert(res.message, 'warning')
              return reject(res.message)
            }
            if (validateNull(res.result.dataList)) {
              return reject('数据列表为空')
            }
            return resolve(res.result.dataList)
          })
          .catch((err) => {
            console.error(err)
            reject(err)
          })
      })
    },
    /** 取消 */
    doCancelEdit() {
      this.visible = false
    },
    /** 一键选择全部数据 */
    doSelectedAll() {
      if (!this.url.list) {
        this.$tap.alert('请设置查询数据地址!')
        return
      }
      this.loading = true
      // 查询条件
      const params = this.getQueryParams()
      // todo 页面大小设为1000，请求全部数据(为了使用排序功能，同时防止请求的数据过多)
      params.pageSize = 1000
      getAction(this.url.list, params)
        .then((res) => {
          if (res.success) {
            this.datas = res.result.dataList
            // 重新加载该页数据，刷新选项
            this.doClearSelected()
            this.$nextTick(() => {
              this.$refs.mainTable.toggleAllSelection()
              this.selectedRows = this.datas
              this.selectedRowKeys = this.datas.map((item) => item[this.fieldKeyComputed])
            })
          } else {
            this.$tap.alert(res.message)
          }
        })
        .catch((err) => {
          console.error(err)
        })
        .finally(() => {
          this.loading = false
        })
    },
    /** 清空数据 */
    doClearAll() {
      this.$tap
        .confirm(`确定要清空选择？`)
        .then((_) => {
          this.selectedRows = []
          this.selectedRowKeys = []
          this.externalSelectedRowKeyList = []
          this.doConfirm()
        })
        .catch((_) => {})
    },
    /** 列表选择改变 */
    doSelectChange(selectedRows) {
      this.selectedRows = selectedRows
      this.selectedRowKeys = []
      for (let i = 0; i < selectedRows.length; i++) {
        this.selectedRowKeys.push(selectedRows[i][this.fieldKeyComputed])
      }
    },
    /** 清空列表选择 */
    doClearSelected(rows) {
      this.selectedRows = []
      this.selectedRowKeys = []
      this.externalSelectedRowKeyList = []
      this.$refs.mainTable.clearSelection()
    },
    /** 表格选中事件*/
    doRowClick(row, column, event) {
      // this.$refs.mainTable.toggleRowSelection(row)
      if (row[this.$refs.mainTable.rowKey] !== this.clickRowkey) {
        this.clickRowkey = row[this.$refs.mainTable.rowKey]
      } else {
        this.clickRowkey = ''
      }
    },
    /** 表格多选行选中样式*/
    doChangeRowClassName({ row, rowIndex }) {
      if (row[this.$refs.mainTable.rowKey] === this.clickRowkey) {
        return 'row-click'
      }
      let color = ''
      this.selectedRowKeys.forEach((key, index) => {
        if (row[this.$refs.mainTable.rowKey] === key) {
          color = topscommConst.tableMulrowSelectedClass
          return false
        }
      })
      return color
    },
    /** 表格列排序 */
    doSortChange(columnInfo, prop, order) {
      if (columnInfo.column === null) {
        return
      }
      // 不排序
      if (validateNull(columnInfo.order)) {
        Object.assign(this.sorterInfo, this.sorterDefaultInfo)
        this.loadData({})
        return
      }
      // 升序或者降序排序
      if (columnInfo.column.sortBy) {
        this.sorterInfo.sidx = columnInfo.column.sortBy
      } else {
        this.sorterInfo.sidx = columnInfo.prop
      }
      this.sorterInfo.sord = columnInfo.order.replace('ending', '')
      this.loadData({})
    },
    /** 每页大小改变 */
    doChangeSize(val) {
      if (this.pageInfo.pageSize !== val) {
        this.pageInfo.pageSize = val
        this.pageInfo.currentPage = 1
        this.loadData({})
      }
    },
    /** 页面跳转 */
    doChangeIndex(val) {
      if (this.pageInfo.currentPage !== val) {
        this.pageInfo.currentPage = val
        this.loadData({})
      }
    },
    /** 外部操作-打开参照 */
    openDialog() {
      if (this.disabled) {
        return
      }
      this.visible = true
    },
    /** 外部操作-执行查询，根据实际情况决定是否需要手工调用resetQueryParam */
    doQueryBySearch() {
      this.pageInfo.currentPage = 1
      this.pageInfo.totalPage = 0
      this.doQuery()
    },
    /** 页面关闭时执行 */
    close() {}
  }
}
